using logging;

/* 一个好的设计应该是这样的...
   interface PowerSocket{
       void power_supply();
   }
   class SocketWith3pin: PowerSocket{ }
   class SocketWith2pin: PowerSocket{ }
   但是如果没有接口呢？...
 */

class SocketWith3pin{
    // if this function is not virtual, Adapter would be aborted.
    public virtual void power_supply_for_3pin(){
        Log.print("powered by 3 pin.");
    }
}

class SocketWith2pin{  // it's different to the 3 pin.
    public virtual void power_supply_for_2pin(){
        Log.print("powered by 2 pin.");
    }
}

class LampWith2pin{
    protected SocketWith2pin _socket;
    public void connect_to_power(SocketWith2pin socket){
        this._socket = socket;
        Log.print("Well done, connect the power socket.");
    }
    public void light(){
        _socket.power_supply_for_2pin();
        Log.print("We light the lamp!");
    }
}

// Adapter to change the 3pin to 2pin.
class Adapter: SocketWith2pin{  // must inherit from the SocketWith2pin, so it can be use as a Socket.
    private SocketWith3pin _socket;
    public Adapter(SocketWith3pin socket){
        _socket = socket;
    }
    public override void power_supply_for_2pin(){  // it has a function of SocketWith2pin class
        _socket.power_supply_for_3pin();  // and it calls function of SocketWith3pin class
    }
}

class Demo{
    static void Main(){
        var lamp = new LampWith2pin();
        var socket = new SocketWith3pin();  // socket is object of SocketWith3pin
#if NO_Adapter
        lamp.connect_to_power(socket);  // Fail to compile...
#else
        var socket2 = new Adapter(socket);  // here, socket is object of SocketWith2pin
        lamp.connect_to_power(socket2);
#endif
        lamp.light();
    }
}